package com.questionnaires.repository;

import com.questionnaires.exception.NotExistsException;
import com.questionnaires.model.User;
import com.questionnaires.utils.UserUtils;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.questionnaires.exception.NotUniqueException;

import java.util.List;

/**
 * User repository implementation.
 *
 * @author ioana.ruca@gmail.com
 */
@Repository(value = "userRepository")
public class UserRepositoryImpl implements UserRepository {

    @Autowired
    private SessionFactory sessionFactory;

    /**
     * {@inheritDoc}
     */
    @Transactional
    public void saveOrUpdate(User user) throws NotUniqueException {
        user.setUsername(user.getLastName()+"_"+user.getFirstName());
       // user.setPassword(user.getLastName()+"_"+user.getFirstName());
        String password= user.getLastName()+"_"+user.getFirstName();
        user.setPassword(UserUtils.encode(password));
        if (findByName(user.getUsername()) != null) {
            throw new NotUniqueException("User with username " + user.getUsername() + " already exists!");
        }
        sessionFactory.getCurrentSession().saveOrUpdate(user);
    }

    /**
     * {@inheritDoc}
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public User findById(Long id) {
        
        return (User) sessionFactory.getCurrentSession().get(User.class, id);
    }

    /**
     * {@inheritDoc}
     */
    @Transactional(propagation = Propagation.SUPPORTS)
    public User findByName(String username) {

        Query query = sessionFactory.getCurrentSession().createQuery("from User user where user.username=:username");
        query.setString("username", username);
        if (query.list().isEmpty()) {
            return null;
        }
        return (User)query.list().get(0);
    }

    /**
     * {@inheritDoc}
     */
    @SuppressWarnings("unchecked")
    @Transactional(propagation = Propagation.SUPPORTS)
    public List<User> findAll() {

        return sessionFactory.getCurrentSession().createQuery("from User order by username").list();
    }

    /**
     * {@inheritDoc}
     */
    @Transactional
    public void deleteById(Long id) throws NotExistsException {
    
        User user = findById(id);
        if (user == null) {
            throw new NotExistsException("No user with id " + id + " exists");
        }
        sessionFactory.getCurrentSession().delete(user);
    }
}
